package org.example.travel_web.service.impl;

import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.yulichang.wrapper.MPJLambdaWrapper;
import jakarta.annotation.Resource;
import org.example.travel_web.dto.PageResult;
import org.example.travel_web.dto.attraction.*;
import org.example.travel_web.entity.AttractionCategoriesET;
import org.example.travel_web.entity.AttractionsET;
import org.example.travel_web.entity.CommentsET;
import org.example.travel_web.entity.UserAttrET;
import org.example.travel_web.enums.Type;
import org.example.travel_web.exception.RunException;
import org.example.travel_web.mapper.AttractionsMapper;
import org.example.travel_web.mapper.CommentsMapper;
import org.example.travel_web.service.AttractionsService;
import org.example.travel_web.service.UserAttrService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

/**
 * @author 23591
 * @description 针对表【travel_attractions(用于存储景点的详细信息)】的数据库操作Service实现
 * @createDate 2025-01-21 15:57:26
 */
@Service
public class AttractionsServiceImpl extends ServiceImpl<AttractionsMapper, AttractionsET>
        implements AttractionsService {

    @Resource
    private CommentsMapper commentsMapper;
    @Resource
    private UserAttrService userAttrService;

    @Override
    public PageResult<PageResp> pageResult(PageReq pageReq) {
        MPJLambdaWrapper<AttractionsET> wrapper = new MPJLambdaWrapper<AttractionsET>()
                .selectAll(AttractionsET.class)
                .selectAll(AttractionCategoriesET.class)
                .selectAs(AttractionCategoriesET::getName, PageResp::getCategoryName);
        if (StrUtil.isNotBlank(pageReq.getKeyword())) {
            wrapper.like(AttractionsET::getName, pageReq.getKeyword());
        }
        if (pageReq.getCategoryId() != null) {
            wrapper.eq(AttractionCategoriesET::getCategoryId, pageReq.getCategoryId());
        }
        wrapper.leftJoin(AttractionCategoriesET.class, AttractionCategoriesET::getCategoryId, AttractionsET::getCategoryId);
        wrapper.orderByDesc(AttractionsET::getAttractionId);
        Page<PageResp> page = getBaseMapper().selectJoinPage(new Page<>(pageReq.getPage(), pageReq.getSize()), PageResp.class, wrapper);
        return PageResult.of(page.getTotal(), page.getCurrent(), page.getSize(), page.getRecords());
    }

    @Override
    public void addAttraction(AttractionReq req) {
        LambdaQueryWrapper<AttractionsET> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(AttractionsET::getName, req.getName());
        if (exists(wrapper)) {
            throw new RunException("景点已存在");
        }
        AttractionsET attractionsET = BeanUtil.toBean(req, AttractionsET.class);
        if (!save(attractionsET)) {
            throw new RunException("添加失败");
        }
    }

    @Override
    public void updateAttraction(AttractionReq req) {
        if (req.getAttractionId() == null) {
            throw new RunException("景点id不能为空");
        }
        LambdaQueryWrapper<AttractionsET> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(AttractionsET::getName, req.getName())
                .ne(AttractionsET::getAttractionId, req.getAttractionId());
        if (exists(wrapper)) {
            throw new RunException("景点已存在");
        }
        if (!updateById(BeanUtil.toBean(req, AttractionsET.class))) {
            throw new RunException("修改失败");
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteAttraction(Integer[] ids) {
        if (!removeByIds(List.of(ids))) {
            throw new RunException("删除失败");
        }
        LambdaQueryWrapper<CommentsET> wrapper = new LambdaQueryWrapper<CommentsET>()
                .eq(CommentsET::getType, Type.ATTRACTION)
                .in(CommentsET::getRelateId, List.of(ids));
        if (commentsMapper.selectCount(wrapper) > 0 && commentsMapper.delete(wrapper) < 1) {
            throw new RunException("删除失败");
        }
        LambdaQueryWrapper<UserAttrET> attrWrapper = new LambdaQueryWrapper<>();
        attrWrapper.eq(UserAttrET::getType, Type.ATTRACTION);
        attrWrapper.in(UserAttrET::getRelateId, List.of(ids));
        if (userAttrService.count(attrWrapper) > 0 && !userAttrService.remove(attrWrapper)) {
            throw new RunException("删除失败");
        }
    }

    @Override
    public AttractionDetail getAttractionDetail(Integer id) {
        MPJLambdaWrapper<AttractionsET> wrapper = new MPJLambdaWrapper<AttractionsET>()
                .selectAll(AttractionsET.class)
                .selectAll(AttractionCategoriesET.class)
                .selectAs(AttractionCategoriesET::getName, AttractionDetail::getCategoryName);
        wrapper.eq(AttractionsET::getAttractionId, id)
                .leftJoin(AttractionCategoriesET.class, AttractionCategoriesET::getCategoryId, AttractionsET::getCategoryId);
        AttractionDetail attractionDetail = getBaseMapper().selectJoinOne(AttractionDetail.class, wrapper);
        if (attractionDetail == null) {
            throw new RunException("景点不存在");
        }
        if (StpUtil.isLogin()){
            LambdaQueryWrapper<UserAttrET> attrWrapper = new LambdaQueryWrapper<>();
            attrWrapper.eq(UserAttrET::getUid, StpUtil.getLoginIdAsLong());
            attrWrapper.eq(UserAttrET::getType, Type.ATTRACTION);
            attrWrapper.eq(UserAttrET::getRelateId, id);
            attractionDetail.setIsCollection(userAttrService.exists(attrWrapper));
        }
        return attractionDetail;
    }

    @Override
    public PageResult<UserAttractionPageResp> userPageResult(UserPageReq req) {
        LambdaQueryWrapper<AttractionsET> wrapper = new LambdaQueryWrapper<>();
        if (req.getCategoryId() != null) {
            wrapper.eq(AttractionsET::getCategoryId, req.getCategoryId());
        }
        if (StrUtil.isNotBlank(req.getKeyword())) {
            wrapper.like(AttractionsET::getName, req.getKeyword());
        }
        wrapper.orderByDesc(AttractionsET::getAttractionId);
        Page<AttractionsET> page = page(new Page<>(req.getPage(), req.getSize()), wrapper);
        return PageResult.of(page.getTotal(), page.getCurrent(), page.getSize(), BeanUtil.copyToList(page.getRecords(), UserAttractionPageResp.class));
    }
}




